package org.aspire.io;

import java.awt.AlphaComposite;
import java.awt.Canvas;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.net.URL;

import org.aspire.graphics.Frame;
import org.aspire.graphics.ImageUtil;
import org.aspire.graphics.Strip;
import org.aspire.graphics.frame.StandardFrame;

/******************************************************************************
 * Utility class for loading and saving images.
 * <p>
 * Note: applicable only to J2SE version.
 * 
 * @author Golden T Studios (GTGE)
 * @author JPACarabuena
 *****************************************************************************/
public final class ImageIO {

	// ========================================================================
	// Constants
	// ========================================================================

	// ========================================================================
	// Static Methods
	// ========================================================================

	// ========================================================================
	// Fields
	// ========================================================================

	/**************************************************************************
	 * The media tracker for this image IO.
	 *************************************************************************/
	private static final MediaTracker tracker = new MediaTracker(new Canvas());
	
	// ========================================================================
	// Constructors
	// ========================================================================

	/**************************************************************************
	 * Hidden constructor to avoid instantiation of this class.
	 *************************************************************************/
	protected ImageIO() {
		
	}
	
	// ========================================================================
	// Getters & Setters
	// ========================================================================

	// ========================================================================
	// Override Methods
	// ========================================================================

	// ========================================================================
	// Methods
	// ========================================================================

	/**************************************************************************
     * Loads an image from URL and specified transparency.
     * 
     * @param url image URL
     * @param transparency image transparency
     * @return Loaded image.
	 *************************************************************************/
	public static Frame getFrame(URL url, int transparency) {
		try {
			Image image = Toolkit.getDefaultToolkit().getImage(url);
			ImageIO.waitForResource(image);
			
			BufferedImage buffer = ImageUtil.createImage(image.getWidth(null), 
					image.getHeight(null), transparency);
			
			Graphics2D g = (Graphics2D) buffer.getGraphics();
			g.setComposite(AlphaComposite.Src);
			g.drawImage(image, 0, 0, null);
			g.dispose();
			
			StandardFrame frame = new StandardFrame();
			frame.setImage(buffer);
			
			return frame;
		} catch(Exception e) {
			return null;
		}
	}
	
	public static Strip getStrip(URL url, int col, int row, int transparency) {
		BufferedImage[] images = ImageUtil.splitImage(
				ImageIO.getFrame(url, transparency), col, row);
		
		Frame[] frames = new Frame[images.length];
		
		int total = images.length;
		
		for(int i = 0; i < total; i++) {
			frames[i] = new StandardFrame();
			frames[i].setImage(images[i]);
		}
		
		Strip strip = new Strip(frames);
		
		return strip;
	}

	/**************************************************************************
	 * Wait for the resource to complete loading.
	 * 
	 * @param image	the image to be loaded.
	 * @throws Exception error during image loading.
	 *************************************************************************/
	private static void waitForResource(Image image) throws Exception {
		if (image == null) {
			throw new NullPointerException();
		}
	      
		try {
			ImageIO.tracker.addImage(image, 0);
			ImageIO.tracker.waitForAll();
			if ((ImageIO.tracker.statusID(0, true) & MediaTracker.ERRORED) != 0) {
				throw new RuntimeException();
			}
		} catch (Exception e) {
			ImageIO.tracker.removeImage(image, 0);
			throw e;
		}
	}
	
	// ========================================================================
	// Inner & Anonymous Classes
	// ========================================================================
}